package game.graphics
{
	import away3d.core.managers.*;
	
	import engine.asset.*;
	import engine.core.*;
	import engine.graphics.postfx.*;
	import engine.graphics.resources.*;
	
	import flash.display.*;
	import flash.display3D.*;
	import flash.geom.*;
	import flash.utils.*;
	
	public class RxVirtualTexture
	{
		private var m_cacheSize:uint;
		private var m_cacheGridWidth:uint;
		private var m_cacheGridHeight:uint;
		private var m_mappedWidth:uint;
		private var m_mappedHeight:uint;
		private var m_cacheGridX0:int;
		private var m_cacheGridY0:int;
		private var m_cacheGridX1:int;
		private var m_cacheGridY1:int;
		private var m_mappedX0:int;
		private var m_mappedY0:int;
		private var m_mappedX1:int;
		private var m_mappedY1:int;
		private var m_mappedCenterX:int;
		private var m_mappedCenterY:int;
		private var m_mappedTextureReady:Boolean;
		private var m_mappedRect:Rectangle;
		private var m_gridRect:Rectangle;
		private var m_gigaTexture:RxGigaTextureInfo;
		private var m_textureLoaders:Vector.<RxAssetImage>;
		private var m_sliceTextures:Vector.<RxGPUTexture2D>;
		private var m_loaderCallbacks:Vector.<RxVirtualTextureCallback>;
		private var m_worker:RxTimerWorker;
		private var m_mappedColorTexture:RxGPUTexture2D;
		private var m_mappedDepthTexture:RxGPUTexture2D;
		private var m_blackTexture:RxGPUTexture2D;
		private var m_whiteTexture:RxGPUTexture2D;
		private var m_numFreeTextures:uint;
		private var m_texturesFreeList:Vector.<RxGPUTexture2D>;
		private var m_textureBlitter:RxTextureBlitter;
		private var m_colorBlitter:RxColorBlitter;
		private var m_numTextureLoads:uint;
		private var m_totalTextureLoadTime:uint;
		private var m_numTextureDecodes:uint;
		private var m_totalTextureDecodeTime:uint;
		public static var s_verbose:uint = 0;
		
		public function RxVirtualTexture(param1:Context3D, param2:uint, param3:uint, param4:uint, param5:RxTimerWorker)
		{
			this.m_cacheSize = param2;
			this.m_mappedWidth = param3;
			this.m_mappedHeight = param4;
			this.m_mappedColorTexture = new RxGPUTexture2D();
			this.m_mappedColorTexture.Create(param1, this.m_mappedWidth, this.m_mappedHeight, Context3DTextureFormat.BGRA, true);
			this.m_mappedDepthTexture = new RxGPUTexture2D();
			this.m_mappedDepthTexture.Create(param1, this.m_mappedWidth, this.m_mappedHeight, Context3DTextureFormat.BGRA, true);
			var _loc_6:* = new BitmapData(1, 1, true, 0);
			this.m_blackTexture = new RxGPUTexture2D();
			this.m_blackTexture.CreateFromBitmapData(param1, _loc_6);
			_loc_6.dispose();
			_loc_6 = null;
			var _loc_7:* = new BitmapData(1, 1, true, 4294967295);
			this.m_whiteTexture = new RxGPUTexture2D();
			this.m_whiteTexture.CreateFromBitmapData(param1, _loc_7);
			_loc_7.dispose();
			_loc_7 = null;
			this.m_textureBlitter = new RxTextureBlitter();
			this.m_textureBlitter.Create(param1, false, false);
			this.m_colorBlitter = new RxColorBlitter();
			this.m_colorBlitter.Create(param1);
			this.m_cacheGridX0 = 0;
			this.m_cacheGridY0 = 0;
			this.m_cacheGridX1 = 0;
			this.m_cacheGridY1 = 0;
			this.m_mappedX0 = 0;
			this.m_mappedY0 = 0;
			this.m_mappedX1 = 0;
			this.m_mappedY1 = 0;
			this.m_mappedCenterX = 0;
			this.m_mappedCenterY = 0;
			this.m_mappedTextureReady = false;
			this.m_mappedRect = new Rectangle(0, 0, 0, 0);
			this.m_gridRect = new Rectangle(0, 0, 0, 0);
			this.m_numTextureLoads = 0;
			this.m_totalTextureLoadTime = 0;
			this.m_numTextureDecodes = 0;
			this.m_totalTextureDecodeTime = 0;
			this.m_worker = param5;
		}
		
		public function IsMappedRegionLoaded(param1:uint) : Boolean
		{
			var _loc_2:int = 0;
			var _loc_3:int = 0;
			var _loc_4:uint = 0;
			if (this.m_gigaTexture == null)
			{
				return false;
			}
			if (this.m_cacheGridX0 == 0 && this.m_cacheGridY0 == 0 && this.m_cacheGridX1 == 0 && this.m_cacheGridY1 == 0)
			{
				return false;
			}
			_loc_3 = this.m_cacheGridY0;
			while (_loc_3 < this.m_cacheGridY1)
			{
				
				_loc_2 = this.m_cacheGridX0;
				while (_loc_2 < this.m_cacheGridX1)
				{
					
					_loc_4 = this.m_gigaTexture.GetSliceIndex(_loc_2, _loc_3);
					if (param1 == RxGigaTextureInfo.TEXTURE_TYPE_DEPTH)
					{
						_loc_4 = _loc_4 + this.m_gigaTexture.GetNumSlices();
					}
					if (this.m_sliceTextures[_loc_4] == null)
					{
						return false;
					}
					_loc_2++;
				}
				_loc_3++;
			}
			return true;
		}
		
		public function UpdateCacheGrid(param1:int, param2:int) : void
		{
			var _loc_5:int = 0;
			var _loc_6:int = 0;
			var _loc_7:int = 0;
			var _loc_8:int = 0;
			var _loc_16:int = 0;
			var _loc_17:int = 0;
			var _loc_3:* = this.m_cacheGridWidth * this.m_gigaTexture.GetSliceWidth();
			var _loc_4:* = this.m_cacheGridHeight * this.m_gigaTexture.GetSliceHeight();
			_loc_5 = param1 - _loc_3 / 2;
			_loc_6 = param2 - _loc_4 / 2;
			_loc_7 = _loc_5 + _loc_3;
			_loc_8 = _loc_6 + _loc_4;
			if (_loc_5 < 0)
			{
				_loc_7 = _loc_7 - _loc_5;
				_loc_5 = 0;
			}
			else if (_loc_7 > this.m_gigaTexture.GetTotalWidth())
			{
				_loc_5 = _loc_5 - (_loc_7 - this.m_gigaTexture.GetTotalWidth());
				_loc_7 = this.m_gigaTexture.GetTotalWidth();
			}
			if (_loc_6 < 0)
			{
				_loc_8 = _loc_8 - _loc_6;
				_loc_6 = 0;
			}
			else if (_loc_8 > this.m_gigaTexture.GetTotalHeight())
			{
				_loc_6 = _loc_6 - (_loc_8 - this.m_gigaTexture.GetTotalHeight());
				_loc_8 = this.m_gigaTexture.GetTotalHeight();
			}
			_loc_5 = (_loc_5 + this.m_gigaTexture.GetSliceWidth() / 2) / this.m_gigaTexture.GetSliceWidth();
			_loc_6 = (_loc_6 + this.m_gigaTexture.GetSliceHeight() / 2) / this.m_gigaTexture.GetSliceHeight();
			_loc_7 = _loc_5 + this.m_cacheGridWidth;
			_loc_8 = _loc_6 + this.m_cacheGridHeight;
			if (_loc_5 == this.m_cacheGridX0 && _loc_6 == this.m_cacheGridY0 && _loc_7 == this.m_cacheGridX1 && _loc_8 == this.m_cacheGridY1)
			{
				return;
			}
			if (s_verbose >= 2)
			{
			}
			var _loc_9:* = this.m_cacheGridX0;
			var _loc_10:* = this.m_cacheGridY0;
			var _loc_11:* = this.m_cacheGridX1;
			var _loc_12:* = this.m_cacheGridY1;
			this.m_cacheGridX0 = _loc_5;
			this.m_cacheGridY0 = _loc_6;
			this.m_cacheGridX1 = _loc_7;
			this.m_cacheGridY1 = _loc_8;
			var _loc_13:* = (this.m_cacheGridX0 + this.m_cacheGridX1) / 2;
			var _loc_14:* = (this.m_cacheGridY0 + this.m_cacheGridY1) / 2;
			var _loc_15:* = this.m_cacheGridX1 - _loc_13 + (this.m_cacheGridY1 - _loc_14);
			if (this.m_cacheGridX0 > _loc_11 || this.m_cacheGridX1 < _loc_9 || this.m_cacheGridY0 > _loc_12 || this.m_cacheGridY1 < _loc_10)
			{
				this.UnloadSlices(_loc_9, _loc_10, _loc_11, _loc_12);
				this.LoadSlices(this.m_cacheGridX0, this.m_cacheGridY0, this.m_cacheGridX1, this.m_cacheGridY1, _loc_13, _loc_14, _loc_15);
			}
			else
			{
				_loc_16 = Math.max(this.m_cacheGridY0, _loc_10);
				_loc_17 = Math.min(this.m_cacheGridY1, _loc_12);
				if (_loc_10 < this.m_cacheGridY0)
				{
					this.UnloadSlices(_loc_9, _loc_10, _loc_11, this.m_cacheGridY0);
				}
				if (_loc_12 > this.m_cacheGridY1)
				{
					this.UnloadSlices(_loc_9, this.m_cacheGridY1, _loc_11, _loc_12);
				}
				if (_loc_9 < this.m_cacheGridX0)
				{
					this.UnloadSlices(_loc_9, _loc_16, this.m_cacheGridX0, _loc_17);
				}
				if (_loc_11 > this.m_cacheGridX1)
				{
					this.UnloadSlices(this.m_cacheGridX1, _loc_16, _loc_11, _loc_17);
				}
				if (_loc_10 > this.m_cacheGridY0)
				{
					this.LoadSlices(this.m_cacheGridX0, this.m_cacheGridY0, this.m_cacheGridX1, _loc_10, _loc_13, _loc_14, _loc_15);
				}
				if (_loc_12 < this.m_cacheGridY1)
				{
					this.LoadSlices(this.m_cacheGridX0, _loc_12, this.m_cacheGridX1, this.m_cacheGridY1, _loc_13, _loc_14, _loc_15);
				}
				if (_loc_9 > this.m_cacheGridX0)
				{
					this.LoadSlices(this.m_cacheGridX0, _loc_16, _loc_9, _loc_17, _loc_13, _loc_14, _loc_15);
				}
				if (_loc_11 < this.m_cacheGridX1)
				{
					this.LoadSlices(_loc_11, _loc_16, this.m_cacheGridX1, _loc_17, _loc_13, _loc_14, _loc_15);
				}
			}
		}
		
		private function LoadSlices(param1:int, param2:int, param3:int, param4:int, param5:int, param6:int, param7:int) : void
		{
			var _loc_8:int = 0;
			var _loc_9:int = 0;
			var _loc_10:int = 0;
			_loc_9 = param2;
			while (_loc_9 < param4)
			{
				
				_loc_8 = param1;
				while (_loc_8 < param3)
				{
					
					_loc_10 = param7 - Math.abs(_loc_8 - param5) - Math.abs(_loc_9 - param6);
					_loc_10 = RxTimerWorker.PRIORITY_LOWEST + (RxTimerWorker.PRIORITY_HIGHEST - RxTimerWorker.PRIORITY_LOWEST) * _loc_10 / param7;
					this.LoadSlice(_loc_8, _loc_9, _loc_10);
					_loc_8++;
				}
				_loc_9++;
			}
		}
		
		private function LoadSlice(param1:uint, param2:uint, param3:int) : void
		{
			var _loc_6:RxVirtualTextureCallback = null;
			var _loc_7:RxAssetImage = null;
			var _loc_8:Boolean = false;
			var _loc_9:Vector.<String> = null;
			var _loc_4:* = this.m_gigaTexture.GetSliceIndex(param1, param2);
			var _loc_5:* = this.m_gigaTexture.GetSliceIndex(param1, param2) + this.m_gigaTexture.GetNumSlices();
			if (this.m_textureLoaders[_loc_4] == null || this.m_textureLoaders[_loc_5] == null)
			{
				_loc_9 = this.m_gigaTexture.GetSliceURLs(_loc_4);
				if (this.m_textureLoaders[_loc_4] == null)
				{
					this.m_loaderCallbacks[_loc_4] = new RxVirtualTextureCallback(this.LoadCallback);
					this.m_loaderCallbacks[_loc_4].m_slice = _loc_4;
					this.m_textureLoaders[_loc_4] = new RxAssetImage();
					this.m_textureLoaders[_loc_4].SetImageForms(RxAssetImage.IMAGE_FORM_COMPRESSED_BYTEARRAY | RxAssetImage.IMAGE_FORM_DECOMPRESSED_BITMAPDATA);
					this.m_textureLoaders[_loc_4].SetURL(_loc_9[RxGigaTextureInfo.TEXTURE_TYPE_COLOR]);
					this.m_textureLoaders[_loc_4].SetCallbackClear(false);
					this.m_textureLoaders[_loc_4].AddCallback(this.m_loaderCallbacks[_loc_4] as RxAssetCallback);
				}
				if (this.m_textureLoaders[_loc_5] == null)
				{
					this.m_loaderCallbacks[_loc_5] = new RxVirtualTextureCallback(this.LoadCallback);
					this.m_loaderCallbacks[_loc_5].m_slice = _loc_5;
					this.m_textureLoaders[_loc_5] = new RxAssetImage();
					this.m_textureLoaders[_loc_5].SetImageForms(RxAssetImage.IMAGE_FORM_COMPRESSED_BYTEARRAY | RxAssetImage.IMAGE_FORM_DECOMPRESSED_BITMAPDATA);
					this.m_textureLoaders[_loc_5].SetURL(_loc_9[RxGigaTextureInfo.TEXTURE_TYPE_DEPTH]);
					this.m_textureLoaders[_loc_5].SetCallbackClear(false);
					this.m_textureLoaders[_loc_5].AddCallback(this.m_loaderCallbacks[_loc_5] as RxAssetCallback);
				}
			}
			_loc_8 = false;
			if (this.m_sliceTextures[_loc_4] == null)
			{
				_loc_6 = this.m_loaderCallbacks[_loc_4];
				_loc_7 = this.m_textureLoaders[_loc_4];
				if (_loc_7.GetCompressedByteArray() == null)
				{
					_loc_6.m_state = RxVirtualTextureCallback.STATE_LOAD_REQUEST;
					_loc_8 = true;
				}
				else if (_loc_7.GetBitmapData() == null)
				{
					_loc_6.m_state = RxVirtualTextureCallback.STATE_DECODE_REQUEST;
				}
				else
				{
					_loc_6.m_state = RxVirtualTextureCallback.STATE_UPLOAD_TO_GPU;
				}
				this.m_worker.AddTask(param3, _loc_6 as RxCallback, _loc_8);
			}
			_loc_8 = false;
			if (this.m_sliceTextures[_loc_5] == null)
			{
				_loc_6 = this.m_loaderCallbacks[_loc_5];
				_loc_7 = this.m_textureLoaders[_loc_5];
				if (_loc_7.GetCompressedByteArray() == null)
				{
					_loc_6.m_state = RxVirtualTextureCallback.STATE_LOAD_REQUEST;
					_loc_8 = true;
				}
				else if (_loc_7.GetBitmapData() == null)
				{
					_loc_6.m_state = RxVirtualTextureCallback.STATE_DECODE_REQUEST;
				}
				else
				{
					_loc_6.m_state = RxVirtualTextureCallback.STATE_UPLOAD_TO_GPU;
				}
				this.m_worker.AddTask(param3, _loc_6 as RxCallback, _loc_8);
			}
			if (s_verbose >= 2)
			{
			}
		}
		
		private function UnloadSlices(param1:int, param2:int, param3:int, param4:int) : void
		{
			var _loc_5:int = 0;
			var _loc_6:int = 0;
			_loc_6 = param2;
			while (_loc_6 < param4)
			{
				
				_loc_5 = param1;
				while (_loc_5 < param3)
				{
					
					this.UnloadSlice(_loc_5, _loc_6);
					_loc_5++;
				}
				_loc_6++;
			}
		}
		
		private function UnloadSlice(param1:uint, param2:uint) : void
		{
			var _loc_5:RxVirtualTextureCallback = null;
			var _loc_3:* = this.m_gigaTexture.GetSliceIndex(param1, param2);
			var _loc_4:* = _loc_3 + this.m_gigaTexture.GetNumSlices();
			_loc_5 = this.m_loaderCallbacks[_loc_3];
			if (_loc_5 != null)
			{
				if (_loc_5.m_state != 0)
				{
					_loc_5.m_state = 0;
					this.m_worker.RemoveTask(_loc_5 as RxCallback, false);
				}
			}
			_loc_5 = this.m_loaderCallbacks[_loc_4];
			if (_loc_5 != null)
			{
				if (_loc_5.m_state != 0)
				{
					_loc_5.m_state = 0;
					this.m_worker.RemoveTask(_loc_5 as RxCallback, false);
				}
			}
			if (this.m_textureLoaders[_loc_3] != null)
			{
				this.m_textureLoaders[_loc_3].UnloadDecompressedBitmapData();
			}
			if (this.m_textureLoaders[_loc_4] != null)
			{
				this.m_textureLoaders[_loc_4].UnloadDecompressedBitmapData();
			}
			if (this.m_sliceTextures[_loc_3] != null)
			{
				this.FreeTexture(this.m_sliceTextures[_loc_3]);
				this.m_sliceTextures[_loc_3] = null;
			}
			if (this.m_sliceTextures[_loc_4] != null)
			{
				this.FreeTexture(this.m_sliceTextures[_loc_4]);
				this.m_sliceTextures[_loc_4] = null;
			}
			if (s_verbose >= 2)
			{
			}
		}
		
		private function FreeTexture(param1:RxGPUTexture2D) : void
		{
			this.m_texturesFreeList[this.m_numFreeTextures] = param1;
			this.m_numFreeTextures = this.m_numFreeTextures + 1;
		}
		
		private function LoadCallback(param1:RxVirtualTextureCallback) : Boolean
		{
			var _loc_2:uint = 0;
			var _loc_3:uint = 0;
			var _loc_4:RxAssetImage = null;
			var _loc_5:BitmapData = null;
			if (param1.m_state == RxVirtualTextureCallback.STATE_LOAD_REQUEST || param1.m_state == RxVirtualTextureCallback.STATE_DECODE_REQUEST)
			{
				if (param1.m_state == RxVirtualTextureCallback.STATE_LOAD_REQUEST)
				{
					param1.m_state = RxVirtualTextureCallback.STATE_LOAD_COMPLETE;
					this.m_textureLoaders[param1.m_slice].Load();
				}
				else if (param1.m_state == RxVirtualTextureCallback.STATE_DECODE_REQUEST)
				{
					param1.m_state = RxVirtualTextureCallback.STATE_DECODE_COMPLETE;
					this.m_textureLoaders[param1.m_slice].Decompress();
				}
				param1.m_time = getTimer();
			}
			else if (param1.m_state == RxVirtualTextureCallback.STATE_LOAD_COMPLETE || param1.m_state == RxVirtualTextureCallback.STATE_DECODE_COMPLETE)
			{
				if (param1.m_result == false)
				{
					return true;
				}
				param1.m_state = RxVirtualTextureCallback.STATE_UPLOAD_TO_GPU;
				_loc_2 = getTimer() - param1.m_time;
				if (param1.m_state == RxVirtualTextureCallback.STATE_LOAD_COMPLETE)
				{
					this.m_numTextureLoads = this.m_numTextureLoads + 1;
					this.m_totalTextureLoadTime = this.m_totalTextureLoadTime + _loc_2;
				}
				else if (param1.m_state == RxVirtualTextureCallback.STATE_DECODE_COMPLETE)
				{
					this.m_numTextureDecodes = this.m_numTextureDecodes + 1;
					this.m_totalTextureDecodeTime = this.m_totalTextureDecodeTime + _loc_2;
				}
				this.m_worker.AddTask(RxTimerWorker.PRIORITY_NORMAL, param1 as RxCallback);
			}
			else if (param1.m_state == RxVirtualTextureCallback.STATE_UPLOAD_TO_GPU)
			{
				param1.m_state = RxVirtualTextureCallback.STATE_READY;
				_loc_3 = param1.m_slice;
				_loc_4 = RxAssetImage(param1.m_asset);
				_loc_5 = _loc_4.GetBitmapData();
				this.SetTexture(_loc_3, _loc_5);
				_loc_4.UnloadDecompressedBitmapData();
			}
			return true;
		}
		
		private function SetTexture(param1:uint, param2:BitmapData) : void
		{
			var _loc_3:uint = 0;
			var _loc_4:uint = 0;
			var _loc_5:uint = 0;
			var _loc_6:uint = 0;
			var _loc_7:int = 0;
			var _loc_8:int = 0;
			_loc_5 = param1 / this.m_gigaTexture.GetNumSlices();
			_loc_6 = param1 - _loc_5 * this.m_gigaTexture.GetNumSlices();
			_loc_4 = _loc_6 / this.m_gigaTexture.GetGridWidth();
			_loc_3 = _loc_6 - _loc_4 * this.m_gigaTexture.GetGridWidth();
			if (_loc_3 >= this.m_cacheGridX0 && _loc_3 < this.m_cacheGridX1 && _loc_4 >= this.m_cacheGridY0 && _loc_4 < this.m_cacheGridY1)
			{
				if (this.m_sliceTextures[param1] == null)
				{
					this.m_sliceTextures[param1] = this.AllocTexture();
					if (s_verbose >= 1 && this.m_sliceTextures[param1] == null)
					{
					}
				}
				if (this.m_sliceTextures[param1] != null)
				{
					_loc_7 = getTimer();
					//this.m_sliceTextures[param1].().uploadFromBitmapData(param2);
					_loc_8 = getTimer();
					if (s_verbose >= 1)
					{
					}
				}
			}
		}
		
		private function AllocTexture() : RxGPUTexture2D
		{
			var _loc_1:RxGPUTexture2D = null;
			if (this.m_numFreeTextures > 0)
			{
				this.m_numFreeTextures = this.m_numFreeTextures - 1;
				_loc_1 = this.m_texturesFreeList[this.m_numFreeTextures];
			}
			return _loc_1;
		}
	}
}